<template>
  <m-form ref="searchFormRef" 
  v-if="option?.showSearch!==false"
  layout='inline' 
  :schema="searchFormSchema" 
  @ok="handleSearchFormOk"
  @reset="handleSearchReset"
  :model="searchFormState"
  v-bind="option?.searchFormProps || {}"
  >
  <template #[searchSlot.templateName]="{column,model}" v-for="searchSlot in searchFormItemSlots">
    <slot :name="searchSlot.slotName" :column="column" :model="model"></slot>
  </template>
</m-form>
  <m-table
    ref="tableRef"
    :cacheKey="cCacheKey"
    :api="option?.api"
    :actions="tableActions"
    :dropdownActions="dropdownActions" 
    :columns="tableColumns"
    v-bind="option?.tableProps || {}"
    >
    <template #[tableSlot.templateName]="data" v-for="tableSlot in tableSlots">
      <slot :name="tableSlot.slotName" v-bind="data || {}"></slot>
    </template>
    <template #tableToolbarLeft v-if="option?.addBtn !== false || Object.keys($slots).includes('menuLeft')">
      <slot name="menuLeft">
        <a-button v-perm="props.option?.addPerms" @click="handleAdd" type="primary" v-if="option?.addBtn !== false">
          <template #icon><PlusOutlined/></template>
          {{ option?.addBtnText || '新增' }}
        </a-button>
      </slot>
    </template>
    <template #tableToolbarCenter v-if="Object.keys($slots).includes('menuCenter')">
      <slot name="menuCenter"></slot>
    </template>
    <template #tableToolbarRight v-if="Object.keys($slots).includes('menuRight')">
      <slot name="menuRight"></slot>
    </template>
    </m-table>
    <component :is="dialogComponent" :option="option" ref="formModalRef" @save-success="handleSaveSuccess">
      <template #appendBefore v-if="Object.keys($slots).includes('appendBefore')">
        <slot name="appendBefore"></slot>
      </template>
      <template #appendCenter v-if="Object.keys($slots).includes('appendCenter')">
        <slot name="appendCenter"></slot>
      </template>
      <template #appendAfter v-if="Object.keys($slots).includes('appendAfter')">
        <slot name="appendAfter"></slot>
      </template>
    </component>
</template>
<script setup lang="ts">
import { PropType, computed, reactive, ref, useSlots } from 'vue'
import { ActionItem, MTableColumnType } from '/@/components/Table/types';
import { CrudType } from './types';
import { MFormItemType, MFormType } from '../Form/types';
import { PlusOutlined } from '@ant-design/icons-vue';
import FormModal from './formModal.vue';
import FormDrawer from './formDrawer.vue';
import { postData } from '.';
import { message } from 'ant-design-vue';
const emits = defineEmits(['search-ok','search-reset'])
const slots = useSlots();
const props = defineProps({
  option: {
    type: Object as PropType<CrudType>
  },
  searchModel: {
    type: Object as PropType<any>
  }
})
// 缓存key
const cCacheKey = computed<String>(()=>{
  return props.option?.cacheKey 
  || (typeof props.option?.api == 'string' ? props.option?.api : 'default_key') 
  || 'default_key'
})
const dialogComponent = computed(()=>{
  if(props.option?.dialogType == 'drawer') {
    return FormDrawer
  }
  return FormModal
})
// 列表表格开始
const tableRef = ref()
// 表列表格定义
const tableColumns = computed<Array<MTableColumnType>>(()=>{
  return props.option?.columns?.filter(column=>column.list !==false) || []
})
// 列表表格结束
// 搜索表单定义开始
// 搜索表单
const searchFormRef = ref()
// 搜索的key
const searchFormKeyMap = {}
// 搜索表单项slots
const searchFormItemSlots = computed<Array<{slotName: String,templateName: any}>>(()=>{
  const res:Array<{slotName: String,templateName: any}> = []
  Object.keys(slots).forEach(key=>{
    if(key.startsWith('searchFormItem-')) {
      res.push({
        slotName: key,
        templateName: key.replace('searchFormItem-','')
      })
    }
  })
  return res
})
// 搜索列定义
const searchColumns = computed<Array<MFormItemType>>(()=>{
  const res : Array<MFormItemType> = []
  props.option?.columns?.filter(column=> column.search && column.searchType).forEach(column=>{
    const name = (column.key || column.dataIndex) as any
    const searchName = `m_${column.searchType}_${(column.key || column.dataIndex)}`
    searchFormKeyMap[name] = searchName
    let placeholder = '请输入' + column.title
    if(['Select', 'Dict'].includes(column.component as string)) {
      placeholder = '请选择'
    }
    res.push({
      name: name,
      label: column.title as string,
      span: column.searchSpan,
      component: column.component as any,
      defaultValue: column.searchDefaultValue || (column?.searchColumnProps?.defaultValue) as any,
      componentProps: {
        placeholder: placeholder,
        ...column.componentProps,
        ...column.searchColumnProps
      }
    })
  })
  return res
})
/**
 * 获取搜索表单默认值
 */
 const getSearchFormDefaultValue = (columns: Array<MFormItemType>) =>{
  const v = {}
  columns.forEach(item=>{
    v[item.name as string] = item.defaultValue
  })
  return v;
}
// 搜索表单数据
const searchFormState = reactive({
  ...getSearchFormDefaultValue(searchColumns.value),
  ...props.searchModel
})
// 搜索表单元数据
const searchFormSchema = computed<MFormType>(()=>{
  return {
    columns: searchColumns.value,
    showOk: true,
    showReset: true,
    okText: props.option?.searchOkBtnText || '查询',
    resetText: props.option?.searchResetBtnText ||  '重置'
  }
})
// 处理搜索提交
const handleSearchFormOk = (values: any) =>{
  const params = {}
  Object.keys(values).forEach(key=>{
    params[searchFormKeyMap[key]] = values[key]
  })
  tableRef.value?.reload(params)
  emits('search-ok', values)
}
// 搜索重置
const handleSearchReset = () =>{
  tableRef.value?.reload()
  emits('search-reset')
}
const geDynamicFormValues = () =>{
  if(props.option?.dynamicFormValues && typeof props.option?.dynamicFormValues == 'function') {
    return props.option.dynamicFormValues() || {}
  }
  return props.option?.dynamicFormValues || {}
}
// 搜索表单定义结束
// 表单相关-start
const formModalRef = ref()
// 打开添加表单
const handleAdd = () =>{
  formModalRef.value?.openDialog({
    ...geDynamicFormValues()
  },'add')
}
// 添加成功回调
const handleSaveSuccess = () =>{
  tableRef.value?.reload()
}
// 表单相关-end
// 表格slots
const tableSlots = computed<Array<{slotName: String,templateName: any}>>(()=>{
  const res:Array<{slotName: String,templateName: any}> = []
  Object.keys(slots).forEach(key=>{
    if(key.startsWith('table-')) {
      res.push({
        slotName: key,
        templateName: key.replace('table-','')
      })
    }
  })
  return res
})
// 操作列定义
const tableActions = ref<Array<ActionItem>>([{
  label: props.option?.viewBtnText || '查看',
  type: 'link',
  icon: 'EyeOutlined',
  divider: true,
  perms: props.option?.viewPerms,
  orderNo: 99,
  ifShow: props.option?.viewBtn !== false,
  onClick(e: any, row: any) {
    formModalRef.value?.openDialog({
      ...row.record,
      ...geDynamicFormValues()
    },'view')
  }
},...props.option?.actions || []])
// 操作-下拉菜单
const dropdownActions = ref<Array<ActionItem>>([{
  label: props.option?.treeProps?.btnText || '子菜单',
  icon: 'PlusOutlined',
  divider: true,
  perms: props.option?.treeProps?.btnPerms,
  orderNo: 9,
  ifShow: props.option?.treeProps !== undefined,
  onClick(e: any, row: any) {
    const record = {}
    record[props.option?.treeProps?.pIdKey || 'parentId'] = row.record[props.option?.treeProps?.idKey||'id']
    formModalRef.value?.openDialog({
      ...record,
      ...geDynamicFormValues()
    },'add')
  }
},{
  label: props.option?.editBtnText || '编辑',
  icon: 'EditOutlined',
  divider: true,
  perms: props.option?.editPerms,
  orderNo: 10,
  ifShow: props.option?.editBtn !== false,
  onClick(e: any, row: any) {
    formModalRef.value?.openDialog({
      ...row.record,
      ...geDynamicFormValues()
    },'edit')
  }
},{
  label: props.option?.delBtnText || '删除',
  icon: 'DeleteOutlined',
  perms: props.option?.delPerms,
  ifShow: props.option?.delBtn !== false,
  divider: true,
  //ifShow: false,
  orderNo: 90,
  popConfirm: {
    title: '是否删除该条记录?',
    confirm(e, row) {
      postData(props.option?.delApi,{
        ids: [row.record.id]
      }).then(()=>{
      message.success(`删除成功`)
      // 刷新列表
      tableRef?.value.reload(searchFormState)
    })
    },
    cancel(e, record) {
      console.log('取消删除', record)
    }
  }
},...props.option?.dropdownActions || []])
defineExpose({
  // 获取搜索表单句柄
  getSearchFormRef() {
    return searchFormRef.value
  },
  // 获取表单句柄
  getFormRef() {
    return formModalRef.value?.getFormRef()
  },
  // 获取表格句柄
  getTableRef() {
    return tableRef.value
  },
  // 获取弹窗句柄
  getDialogRef() {
    return formModalRef.value
  },
  openDialog(data: any,mViewType: string){
    formModalRef.value?.openDialog(data,mViewType)
  },
  closeDialog() {
    formModalRef.value?.closeDialog()
  }
})
</script>
<style lang="less" scoped>

</style>